package com.management.department.teacherinfosystem.Service;

import com.management.department.teacherinfosystem.DTO.CourseHoursSubmitDTO;
import com.management.department.teacherinfosystem.DTO.CourseHoursDTO;
import com.management.department.teacherinfosystem.Entity.CourseHours;
import com.management.department.teacherinfosystem.Entity.CourseHoursMember;
import com.management.department.teacherinfosystem.Entity.User;
import com.management.department.teacherinfosystem.Repository.CourseHoursRepository;
import com.management.department.teacherinfosystem.Repository.CourseHoursMemberRepository;
import com.management.department.teacherinfosystem.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.stream.Collectors;

@Service
public class CourseHoursServiceImpl implements CourseHoursService {
    
    @Autowired
    private CourseHoursRepository courseHoursRepository;
    
    @Autowired
    private CourseHoursMemberRepository memberRepository;
    
         @Autowired
     private UserRepository userRepository;
    
    @Override
    @Transactional
    public CourseHours createCourseHours(CourseHoursSubmitDTO dto, Long createdBy) {
        // 创建教学课时
        CourseHours courseHours = new CourseHours();
        courseHours.setAcademicYear(dto.getAcademicYear());
        courseHours.setCourseName(dto.getCourseName());
        courseHours.setCourseNature(dto.getCourseNature());
        courseHours.setTheoryHours(dto.getTheoryHours());
        courseHours.setTeachingClass(dto.getTeachingClass());
        courseHours.setStudentCount(dto.getStudentCount());
        courseHours.setStandardClassCount(dto.getStandardClassCount());
        courseHours.setConversionFactor(dto.getConversionFactor());
        courseHours.setCreatedBy(createdBy);
        
        // 在应用层计算标准课时量和折合课时量
        BigDecimal standardHours = dto.getTheoryHours().multiply(dto.getStandardClassCount());
        BigDecimal convertedHours = standardHours.multiply(dto.getConversionFactor());
        
        courseHours.setStandardHours(standardHours);
        courseHours.setConvertedHours(convertedHours);
        
        // 保存教学课时
        courseHours = courseHoursRepository.save(courseHours);
        
        // 保存成员信息
        if (dto.getMembers() != null) {
            for (CourseHoursSubmitDTO.CourseMemberDTO memberDto : dto.getMembers()) {
                CourseHoursMember member = new CourseHoursMember();
                member.setCourseHoursId(courseHours.getId());
                member.setUserName(memberDto.getUserName());
                member.setAllocatedHours(memberDto.getAllocatedHours());
                member.setRole(memberDto.getRole());
                memberRepository.save(member);
            }
        }
        
        // 调试日志：验证计算
        System.out.println("=== 创建教学课时 - 应用层计算验证 ===");
        System.out.println("课程名称: " + courseHours.getCourseName());
        System.out.println("理论学时: " + courseHours.getTheoryHours());
        System.out.println("折合标准教学班: " + courseHours.getStandardClassCount());
        System.out.println("折算系数: " + courseHours.getConversionFactor());
        System.out.println("计算的标准课时量: " + standardHours);
        System.out.println("计算的折合课时量: " + convertedHours);
        System.out.println("存储的标准课时量: " + courseHours.getStandardHours());
        System.out.println("存储的折合课时量: " + courseHours.getConvertedHours());
        System.out.println("=====================================");
        
        return courseHours;
    }
    
         @Override
     @Transactional
     public CourseHours updateCourseHours(Long id, CourseHoursSubmitDTO dto) {
         CourseHours courseHours = courseHoursRepository.findById(id)
                 .orElseThrow(() -> new RuntimeException("教学课时不存在"));
         
         // 更新基本信息
         courseHours.setAcademicYear(dto.getAcademicYear());
         courseHours.setCourseName(dto.getCourseName());
         courseHours.setCourseNature(dto.getCourseNature());
         courseHours.setTheoryHours(dto.getTheoryHours());
         courseHours.setTeachingClass(dto.getTeachingClass());
         courseHours.setStudentCount(dto.getStudentCount());
         courseHours.setStandardClassCount(dto.getStandardClassCount());
         courseHours.setConversionFactor(dto.getConversionFactor());
         
         // 在应用层重新计算标准课时量和折合课时量
         BigDecimal standardHours = dto.getTheoryHours().multiply(dto.getStandardClassCount());
         BigDecimal convertedHours = standardHours.multiply(dto.getConversionFactor());
         
         courseHours.setStandardHours(standardHours);
         courseHours.setConvertedHours(convertedHours);
         
         // 保存更新
         courseHours = courseHoursRepository.save(courseHours);
         
         // 先删除旧的成员信息（在事务中执行）
         List<CourseHoursMember> existingMembers = memberRepository.findByCourseHoursId(id);
         System.out.println("删除旧成员数量: " + existingMembers.size());
         memberRepository.deleteAll(existingMembers);
         
         // 验证删除是否成功
         List<CourseHoursMember> remainingMembers = memberRepository.findByCourseHoursId(id);
         System.out.println("删除后剩余成员数量: " + remainingMembers.size());
         
         // 保存新的成员信息
         if (dto.getMembers() != null) {
             System.out.println("准备保存新成员数量: " + dto.getMembers().size());
             for (CourseHoursSubmitDTO.CourseMemberDTO memberDto : dto.getMembers()) {
                 CourseHoursMember member = new CourseHoursMember();
                 member.setCourseHoursId(courseHours.getId());
                 member.setUserName(memberDto.getUserName());
                 member.setAllocatedHours(memberDto.getAllocatedHours());
                 member.setRole(memberDto.getRole());
                 
                 // 添加调试日志
                 System.out.println("保存成员: courseHoursId=" + courseHours.getId() + 
                                  ", userName=" + memberDto.getUserName() + 
                                  ", allocatedHours=" + memberDto.getAllocatedHours());
                 
                 memberRepository.save(member);
             }
             
             // 验证保存是否成功
             List<CourseHoursMember> savedMembers = memberRepository.findByCourseHoursId(courseHours.getId());
             System.out.println("保存后成员数量: " + savedMembers.size());
         }
         
         // 调试日志：验证更新后的计算
         System.out.println("=== 更新教学课时 - 应用层计算验证 ===");
         System.out.println("课程名称: " + courseHours.getCourseName());
         System.out.println("理论学时: " + courseHours.getTheoryHours());
         System.out.println("折合标准教学班: " + courseHours.getStandardClassCount());
         System.out.println("折算系数: " + courseHours.getConversionFactor());
         System.out.println("更新后的标准课时量: " + courseHours.getStandardHours());
         System.out.println("更新后的折合课时量: " + courseHours.getConvertedHours());
         System.out.println("=====================================");
         
         return courseHours;
     }
    
    @Override
    @Transactional
    public void deleteCourseHours(Long id) {
        courseHoursRepository.deleteById(id);
    }
    
    @Override
    @Transactional(readOnly = true)
    public CourseHours getCourseHoursById(Long id) {
        return courseHoursRepository.findById(id).orElse(null);
    }
    
    @Override
    @Transactional(readOnly = true)
    public CourseHoursDTO getCourseHoursDTOById(Long id) {
        CourseHours courseHours = courseHoursRepository.findById(id).orElse(null);
        if (courseHours == null) {
            return null;
        }
        return convertToDTO(courseHours);
    }
    
         @Override
     @Transactional(readOnly = true)
     public List<CourseHours> getMyCourseHours(Long userId) {
         // 简化逻辑：先只返回用户创建的教学课时
         List<CourseHours> createdByUser = courseHoursRepository.findByCreatedBy(userId);
         
         // 调试日志
         System.out.println("用户ID: " + userId + ", 创建的教学课时数量: " + createdByUser.size());
         
         return createdByUser;
     }
     
     @Override
     @Transactional(readOnly = true)
     public List<CourseHoursDTO> getMyCourseHoursDTO(Long userId) {
         List<CourseHours> courseHours = getMyCourseHours(userId);
         return courseHours.stream().map(this::convertToDTO).toList();
     }
    
    @Override
    @Transactional(readOnly = true)
    public List<CourseHours> getAllCourseHours() {
        return courseHoursRepository.findAll();
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<CourseHoursDTO> getAllCourseHoursDTO() {
        List<CourseHours> courseHours = courseHoursRepository.findAll();
        return courseHours.stream().map(this::convertToDTO).toList();
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<CourseHours> getCourseHoursByAcademicYear(String academicYear) {
        return courseHoursRepository.findByAcademicYear(academicYear);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<CourseHoursDTO> getCourseHoursDTOByAcademicYear(String academicYear) {
        List<CourseHours> courseHours = courseHoursRepository.findByAcademicYear(academicYear);
        return courseHours.stream().map(this::convertToDTO).toList();
    }
    
         @Override
     @Transactional(readOnly = true)
     public List<CourseHours> getCourseHoursByUserName(String userName) {
         return courseHoursRepository.findByMemberUserName(userName);
     }
     
     @Override
     @Transactional(readOnly = true)
     public List<CourseHoursDTO> getCourseHoursDTOByUserName(String userName) {
         List<CourseHours> courseHours = courseHoursRepository.findByMemberUserName(userName);
         return courseHours.stream().map(this::convertToDTO).toList();
     }
     
     @Override
     @Transactional(readOnly = true)
     public List<CourseHours> getCourseHoursByUserNameAndAcademicYear(String userName, String academicYear) {
         return courseHoursRepository.findByMemberUserNameAndAcademicYear(userName, academicYear);
     }
     
     @Override
     @Transactional(readOnly = true)
     public List<CourseHoursDTO> getCourseHoursDTOByUserNameAndAcademicYear(String userName, String academicYear) {
         List<CourseHours> courseHours = courseHoursRepository.findByMemberUserNameAndAcademicYear(userName, academicYear);
         return courseHours.stream().map(this::convertToDTO).toList();
     }
    
    @Override
    @Transactional(readOnly = true)
    public Double getTotalStandardHoursByAcademicYear(String academicYear) {
        return courseHoursRepository.sumStandardHoursByAcademicYear(academicYear);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Double getTotalConvertedHoursByAcademicYear(String academicYear) {
        return courseHoursRepository.sumConvertedHoursByAcademicYear(academicYear);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Double getTotalStandardHoursByUserId(Long userId) {
        return courseHoursRepository.sumStandardHoursByCreatedBy(userId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Double getTotalConvertedHoursByUserId(Long userId) {
        return courseHoursRepository.sumConvertedHoursByCreatedBy(userId);
    }
    
    @Override
    @Transactional(readOnly = true)
    public List<Object> getTeachersList() {
        // 从教学课时中获取所有创建者信息
        List<CourseHours> courseHours = courseHoursRepository.findAll();
        return courseHours.stream()
            .filter(ch -> ch.getCreatedBy() != null)
            .map(ch -> {
                Map<String, Object> teacher = new HashMap<>();
                teacher.put("id", ch.getCreatedBy());
                
                // 尝试从用户表获取真实姓名
                try {
                    var user = userRepository.findById(ch.getCreatedBy());
                    if (user.isPresent()) {
                        // 优先使用真实姓名字段，如果没有则使用用户名
                        String realName = user.get().getName();
                        if (realName != null && !realName.trim().isEmpty()) {
                            teacher.put("name", realName);
                        } else {
                            teacher.put("name", user.get().getUsername());
                        }
                    } else {
                        teacher.put("name", "用户" + ch.getCreatedBy());
                    }
                } catch (Exception e) {
                    teacher.put("name", "用户" + ch.getCreatedBy());
                }
                
                return teacher;
            })
            .distinct()
            .collect(Collectors.toList());
    }
    
    // 转换为DTO的辅助方法
    private CourseHoursDTO convertToDTO(CourseHours courseHours) {
        CourseHoursDTO dto = new CourseHoursDTO();
        dto.setId(courseHours.getId());
        dto.setAcademicYear(courseHours.getAcademicYear());
        dto.setCourseName(courseHours.getCourseName());
        dto.setCourseNature(courseHours.getCourseNature());
        dto.setTheoryHours(courseHours.getTheoryHours());
        dto.setTeachingClass(courseHours.getTeachingClass());
        dto.setStudentCount(courseHours.getStudentCount());
        dto.setStandardClassCount(courseHours.getStandardClassCount());
        dto.setStandardHours(courseHours.getStandardHours());
        dto.setConversionFactor(courseHours.getConversionFactor());
        dto.setConvertedHours(courseHours.getConvertedHours());
        dto.setCreatedBy(courseHours.getCreatedBy());
        dto.setCreatedAt(courseHours.getCreatedAt());
        dto.setUpdatedAt(courseHours.getUpdatedAt());
        
        // 获取创建者姓名
        if (courseHours.getCreatedBy() != null) {
            try {
                var user = userRepository.findById(courseHours.getCreatedBy());
                if (user.isPresent()) {
                    String realName = user.get().getName();
                    if (realName != null && !realName.trim().isEmpty()) {
                        dto.setCreatorName(realName);
                    } else {
                        dto.setCreatorName(user.get().getUsername());
                    }
                } else {
                    dto.setCreatorName("用户" + courseHours.getCreatedBy());
                }
            } catch (Exception e) {
                dto.setCreatorName("用户" + courseHours.getCreatedBy());
            }
        }
        
        // 获取成员信息
        List<CourseHoursMember> members = memberRepository.findByCourseHoursId(courseHours.getId());
        dto.setMembers(members.stream().map(this::convertMemberToDTO).toList());
        
        return dto;
    }
    
    private CourseHoursDTO.CourseMemberDTO convertMemberToDTO(CourseHoursMember member) {
        CourseHoursDTO.CourseMemberDTO dto = new CourseHoursDTO.CourseMemberDTO();
        dto.setId(member.getId());
        dto.setUserName(member.getUserName());
        dto.setAllocatedHours(member.getAllocatedHours());
        dto.setRole(member.getRole());
        dto.setCreatedAt(member.getCreatedAt());
        
                 return dto;
     }
     
     // 根据用户ID获取用户姓名的辅助方法
     private String getUserNameById(Long userId) {
         try {
             var user = userRepository.findById(userId);
             if (user.isPresent()) {
                 String realName = user.get().getName();
                 if (realName != null && !realName.trim().isEmpty()) {
                     return realName;
                 } else {
                     return user.get().getUsername();
                 }
             }
         } catch (Exception e) {
             // 记录警告信息
             System.out.println("获取用户姓名失败: " + e.getMessage());
         }
         return "用户" + userId;
     }
}
